<?php
/*
 * @Author: lokei
 * @Date: 2022-08-18 16:41:34
 * @LastEditors: lokei
 * @LastEditTime: 2022-09-26 16:49:22
 * @Description: 
 */

namespace App\Http\Controllers\Pay\Weixin;

use App\Models\Pay\ConfModel;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Builder;
use WeChatPay\Util\PemUtil;

class Init
{
    public static function getInstance()
    {
        $conf = ConfModel::first();

        $merchantId = $conf->mchid;

        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = 'file://' . env('ATTACHMENT_ROOT') . $conf->key_file;
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);

        $merchantCertificateFilePath = 'file://' . env('ATTACHMENT_ROOT') . $conf->cert_file;
        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = PemUtil::parseCertificateSerialNo($merchantCertificateFilePath);

        $certs = [];
        $cert_exists = false;
        if (!is_null($conf->wxpay_platform_certs) && $conf->wxpay_platform_certs != '') {
            $certs_array = json_decode($conf->wxpay_platform_certs);
            if (count($certs_array) > 0) {
                $cert_exists = true;
                foreach ($certs_array as $cert_info) {
                    $platformCertificateFilePath = 'file://' . env('ATTACHMENT_ROOT') . 'wxpay/' . 'wechatpay_' . $cert_info->serial_no . '.pem';
                    if (config('app.proj_identity') != null && config('app.proj_identity') != '') {
                        $platformCertificateFilePath = 'file://' . env('ATTACHMENT_ROOT') . config('app.proj_identity') . '/' . 'wxpay/' . 'wechatpay_' . $cert_info->serial_no . '.pem';
                    }
                    $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
                    $certs[$cert_info->serial_no] = $platformPublicKeyInstance;
                }
            }
        }
        if (!$cert_exists) {
            $certs = ['any' => null];
        }

        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => &$certs,
        ]);
        return $instance;
    }
}
